﻿/*
 * msginfo.cpp
 *
 *  Created on: 2017年3月17日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_OS_MSG DM_API_EXPORT

#include <dm/os/msg/msginfo.hpp>
#include <cstring>

namespace dm{

namespace msg{

const char* msgTypeString( const EMsgType& type ){
	switch(type){
	case Msg_Test:
		return "测试";
	case Msg_SyncClock:
		return "时钟同步";
	case Msg_Call:
		return "召唤";
	case Msg_RemoteCtl:
		return "远控";
	case Msg_Set:
		return "设置";
	case Msg_Get:
		return "获取";
	case Msg_Update:
		return "更新";
	case Msg_SyncData:
		return "数据同步";
	case Msg_RemoteReset:
		return "远程同步";
	default:
		return "未知";
	}
}

const char* msgAckString( const EMsgAck& ack ){
	switch( ack ){
	case MaNoAck:
		return "请求";
	case MaAck:
		return "请求须确认";
	case MaSuccess:
		return "反馈成功";
	case MaPart:
		return "反馈部分成功";
	case MaFail:
		return "反馈失败";
	case MaTimeout:
		return "反馈失败：超时";
	case MaDeny:
		return "反馈失败：拒绝执行";
	case MaBusy:
		return "反馈失败：当前繁忙";
	case MaParas:
		return "反馈失败：参数错误";
	case MaIndex:
		return "反馈失败：索引错误";
	default:
		return "未知确认状态";
	}
}

const char* msgRemoteCtlString( const ERemoteControl& ctl ){
	switch( ctl ){
	case Rc_PreOpen:
		return "预控分";
	case Rc_PreClose:
		return "预控合";
	case Rc_Open:
		return "控分";
	case Rc_Close:
		return "控合";
	default:
		return "未知控制命令";
	}
}

size_t SParaData::dataLen()const{
	switch( type ){
	case DtBinary:
		if( num>maxNum_binary() )
			return 0;
		return num;
	case DtInt8:
		if( num>maxNum_int8() )
			return 0;
		return num;
	case DtUint8:
		if( num>maxNum_uint8() )
			return 0;
		return num;
	case DtInt16:
		if( num>maxNum_int16() )
			return 0;
		return num*2;
	case DtUint16:
		if( num>maxNum_uint16() )
			return 0;
		return num*2;
	case DtInt32:
		if( num>maxNum_int32() )
			return 0;
		return num*4;
	case DtUint32:
		if( num>maxNum_uint32() )
			return 0;
		return num*4;
	case DtInt64:
		if( num>maxNum_int64() )
			return 0;
		return num*8;
	case DtUint64:
		if( num>maxNum_uint64() )
			return 0;
		return num*8;
	case DtFloat32:
		if( num>maxNum_float32() )
			return 0;
		return num*4;
	case DtFloat64:
		if( num>maxNum_float64() )
			return 0;
		return num*8;
	case DtString:
		if( num>maxNum_string() )
			return 0;
		return num;
	default:
		return 0;
	}
}

void SParaData::clone( const SParaData& pd ){
	index = pd.index;
	num = pd.num;
	type = pd.type;
	size_t l = dataLen();
	if( l>0 )
		memcpy(data.d_u8,pd.data.d_u8,dataLen());
}

const char* SParaData::typeString( const SParaData::EDataType& type ){
	switch( type ){
	case DtBinary:
		return "Binary";
	case DtInt8:
		return "Int8";
	case DtUint8:
		return "UInt8";
	case DtInt16:
		return "Int16";
	case DtUint16:
		return "UInt16";
	case DtInt32:
		return "Int32";
	case DtUint32:
		return "UInt32";
	case DtInt64:
		return "Int64";
	case DtUint64:
		return "UInt64";
	case DtFloat32:
		return "Float32";
	case DtFloat64:
		return "Float64";
	case DtString:
		return "String";
	default:
		return "未知数据类型";
	}
}

const char* msgSyncTypeString( const ESyncDataType& type ){
	switch(type){
	case SDT_None:
		return "不同步";
	case SDT_Status:
		return "同步状态量";
	case SDT_Discrete:
		return "同步离散量";
	case SDT_Measure:
		return "同步测量量";
	case SDT_Cumulant:
		return "同步累计量";
	case SDT_All:
		return "同步全部";
	default:
		return "错误的同步类型";
	}
}
}

namespace os{
namespace msg{

using namespace dm::msg;

CMsgInfo::CMsgInfo( const mod_t& mod,const EMsgType& type,const EMsgAck& ack)
:m_mod(mod),m_type(type),m_ack(ack),m_ts(){
}

CMsgInfo::CMsgInfo( const CMsgInfo& info ):
		m_mod(info.m_mod),
		m_type(info.m_type),
		m_ack(info.m_ack),
		m_ts(info.m_ts){
	std::memcpy(&m_data,&(info.m_data),sizeof(m_data));
}

CMsgInfo& CMsgInfo::operator =( const CMsgInfo& info ){
	m_mod = info.m_mod;
	m_type = info.m_type;
	m_ack = info.m_ack;
	m_ts = info.m_ts;
	std::memcpy(&m_data,&(info.m_data),sizeof(m_data));

	return *this;
}

void CMsgInfo::setRequest_test( const bool& needAck ){
	m_type = Msg_Test;
	m_ack = needAck?MaAck:MaNoAck;
}

void CMsgInfo::setAnswer_test( const EMsgAck& ack ){
	m_type = Msg_Test;
	m_ack = ack;
}

void CMsgInfo::setRequest_call( const SCallInfo::group_t& group,const bool& needAck ){
	m_type = Msg_Call;
	m_ack = needAck?MaAck:MaNoAck;
	m_data.call.group = group;
}

void CMsgInfo::setAnswer_call( const SCallInfo::group_t& group,const EMsgAck& ack ){
	m_type = Msg_Call;
	m_ack = ack;
	m_data.call.group = group;
}

void CMsgInfo::setRequest_syncClock( const bool& needAck ){
	m_type = Msg_SyncClock;
	m_ack = needAck?MaAck:MaNoAck;
}

void CMsgInfo::setAnswer_syncClock( const EMsgAck& ack ){
	m_type = Msg_SyncClock;
	m_ack = ack;
}

void CMsgInfo::setRequest_remoteCtl( const dm::msg::index_t& index,const ERemoteControl& ctl,const bool& needAck ){
	m_type = Msg_RemoteCtl;
	m_ack = needAck?MaAck:MaNoAck;
	m_data.remoteCtl.index = index;
	m_data.remoteCtl.remoteCtl = ctl;
}

void CMsgInfo::setAnswer_remoteCtl( const SRemoteCtlInfo& ctl,const EMsgAck& ack ){
	m_type = Msg_RemoteCtl;
	m_ack = ack;
	m_data.remoteCtl.index = ctl.index;
	m_data.remoteCtl.remoteCtl = ctl.remoteCtl;
}

void CMsgInfo::setAnswer_remoteCtl( const dm::msg::index_t& index,const dm::msg::ERemoteControl& ctl,const dm::msg::EMsgAck& ack ){
	m_type = Msg_RemoteCtl;
	m_ack = ack;
	m_data.remoteCtl.index = index;
	m_data.remoteCtl.remoteCtl = ctl;
}

void CMsgInfo::setRequest_set( const dm::msg::index_t& index,const dm::msg::index_t& num,const bool& needAck ){
	m_type = Msg_Set;
	m_ack = needAck?MaAck:MaNoAck;
	m_data.paraData.index = index;
	m_data.paraData.num = num;
}

void CMsgInfo::setAnswer_set( const dm::msg::index_t& index,const dm::msg::index_t& num,const EMsgAck& ack ){
	m_type = Msg_Set;
	m_ack = ack;
	m_data.paraData.index = index;
	m_data.paraData.num = num;
}

void CMsgInfo::setAnswer_set( const SParaData& paraData,const EMsgAck& ack ){
	m_type = Msg_Set;
	m_ack = ack;
	m_data.para.index = paraData.index;
	m_data.para.num = paraData.num;
}

void CMsgInfo::setRequest_get( const dm::msg::index_t& index,const dm::msg::index_t& num,const bool& needAck ){
	m_type = Msg_Get;
	m_ack = needAck?MaAck:MaNoAck;
	m_data.para.index = index;
	m_data.para.num = num;
}

void CMsgInfo::setAnswer_get( const SParaInfo& paraInfo,const EMsgAck& ack ){
	m_type = Msg_Get;
	m_ack = ack;
	m_data.paraData.index = paraInfo.index;
	m_data.paraData.num = paraInfo.num;
}

void CMsgInfo::setAnswer_get( const SParaData& pd,const EMsgAck& ack ){
	m_type = Msg_Get;
	m_ack = ack;
	memcpy(&m_data.paraData,&pd,sizeof(pd));
}

void CMsgInfo::setRequest_update( const dm::msg::index_t& index,const dm::msg::index_t& num,const bool& needAck ){
	m_type = Msg_Update;
	m_ack = needAck?MaAck:MaNoAck;
	m_data.paraData.index = index;
	m_data.paraData.num = num;
}

void CMsgInfo::setAnswer_update( const dm::msg::index_t& index,const dm::msg::index_t& num,const EMsgAck& ack ){
	m_type = Msg_Update;
	m_ack = ack;
	m_data.paraData.index = index;
	m_data.paraData.num = num;
}

void CMsgInfo::setAnswer_update( const SParaData& paraData,const EMsgAck& ack ){
	m_type = Msg_Update;
	m_ack = ack;
	m_data.para.index = paraData.index;
	m_data.para.num = paraData.num;
}

void CMsgInfo::setRequest_sync( const ESyncDataType& type,const bool& needAck ){
	m_type = Msg_SyncData;
	m_ack = needAck?MaAck:MaNoAck;
	m_data.sync.type = type;
}

void CMsgInfo::setAnswer_sync( const SSyncInfo& sync,const EMsgAck& ack ){
	m_type = Msg_SyncData;
	m_ack = ack;
	m_data.sync.type = sync.type;
}

void CMsgInfo::setAnswer_sync( const ESyncDataType& type,const EMsgAck& ack ){
	m_type = Msg_SyncData;
	m_ack = ack;
	m_data.sync.type = type;
}

void CMsgInfo::setRequest_remoteReset( const bool& needAck ){
	m_type = Msg_RemoteReset;
	m_ack = needAck?MaAck:MaNoAck;
}

void CMsgInfo::setAnswer_remoteReset( const EMsgAck& ack ){
	m_type = Msg_RemoteReset;
	m_ack = ack;
}

}
}
}


